﻿using AbpMvc.Demo.Routes;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore;
using System;
using System.Collections.Generic;
using System.IO;

namespace AbpMvc.Demo.EntityFrameworkCore;

/* This class is needed for EF Core console commands
 * (like Add-Migration and Update-Database commands) */
public class DemoDbContextFactory : IDesignTimeDbContextFactory<DemoDbContext>
{
    private static IServiceProvider _serviceProvider;
    static DemoDbContextFactory()
    {
        var services = new ServiceCollection();

        services.AddShardingDbContext<DemoDbContext>()
            .UseRouteConfig(op =>
            {
                op.AddShardingDataSourceRoute<TodoDataSourceRoute>();
                op.AddShardingTableRoute<TodoTableRoute>();
            })
            .UseConfig((sp, op) =>
            {
                op.UseShardingQuery((conStr, builder) =>
                {
                    builder.UseSqlServer(conStr);
                });
                op.UseShardingTransaction((connection, builder) =>
                {
                    builder.UseSqlServer(connection);
                });
                op.UseShardingMigrationConfigure(builder =>
                {
                    builder.ReplaceService<IMigrationsSqlGenerator, ShardingSqlServerMigrationsSqlGenerator>();
                });
                op.AddDefaultDataSource("ds0", "Server=(LocalDb)\\MSSQLLocalDB;Database=Demo;Trusted_Connection=True;TrustServerCertificate=true");
                op.AddExtraDataSource(sp =>
                {
                    return new Dictionary<string, string>()
                        {
                            { "ds1", "Server=(LocalDb)\\MSSQLLocalDB;Database=Demo1;Trusted_Connection=True;TrustServerCertificate=true" },
                            { "ds2", "Server=(LocalDb)\\MSSQLLocalDB;Database=Demo2;Trusted_Connection=True;TrustServerCertificate=true" }
                        };
                });
            })
            .AddShardingCore();
        _serviceProvider = services.BuildServiceProvider();
    }
    public DemoDbContext CreateDbContext(string[] args)
    {
        var configuration = BuildConfiguration();
        
        DemoEfCoreEntityExtensionMappings.Configure();

        var builder = new DbContextOptionsBuilder<DemoDbContext>()
            .UseSqlServer(configuration.GetConnectionString("Default"));
        
        return new DemoDbContext(builder.Options);
    }

    private static IConfigurationRoot BuildConfiguration()
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../AbpMvc.Demo.DbMigrator/"))
            .AddJsonFile("appsettings.json", optional: false);

        return builder.Build();
    }
}
